
open Namespace_ast

let rec build_post_ast e = function
	| [] -> ALeftHandSide e
	| a::lst ->ALeftHandSideOp (
		ANewExpression(
			AMemberExpression (
				APrimaryExpr (
					AExpression [
						ACondExpr(
							ACondBinaryExpr(
								AUnaryExpr(
									APostfixExpr(build_post_ast e lst))))]))), a)
									
			
let build_functionFromAssign t f expr = 
	let func = ((match t with 
	| None -> false
	| Some _ -> true),
	None, (match f with
	| None -> []
	| Some f -> f), [AStatement(AReturnStatement(Some(
	[expr])))]) in
		ACondBinaryExpr(
			AUnaryExpr(
				APostfixExpr(ALeftHandSide (
		ANewExpression(
			AMemberExpression (AFunctionExpr(func)))))))
			
let build_function t f expr = build_functionFromAssign t f (ACondExpr expr)

let build_assignFromLeftHandSide e = 
	(ACondExpr(ACondBinaryExpr(AUnaryExpr(
	APostfixExpr(ALeftHandSide(e))))))

let build_assignFromPrimary e = 
	build_assignFromLeftHandSide (ANewExpression(
	AMemberExpression(APrimaryExpr(e))))

let build_comprehensionList map predsArray =
	let predsArray, args = List.fold_left (fun (lst, args) e -> match e with
	| ACondExpr(ACondBinaryExpr(ABinaryExpr ("in", AUnaryExpr(
				APostfixExpr(ALeftHandSide (
		ANewExpression(
			AMemberExpression (APrimaryExpr(AIdentifier(ident))))))), e))) -> 
			(lst@[([], ACondExpr(ACondBinaryExpr(e)))]), (args@[ident])
	| _ -> (lst@[([], ACondExpr(build_functionFromAssign None (Some args) e))]), args
	) ([], []) predsArray in
	let predsArray = build_assignFromPrimary (AArrayLiteral (AElements predsArray)) in
	let map = ACondExpr(build_functionFromAssign None (Some args) (ACondExpr(ACondBinaryExpr(map)))) in
	let call = ACallMemberArgs(
		AMemberDotExpr(
		AMemberDotExpr(
		APrimaryExpr(AIdentifier("jlang")),
		"list"),
		"comprehension"),
		map :: predsArray :: []) in
	[build_assignFromLeftHandSide (ACallExpression(call))]
